﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Yozeev.BusinessLogic;
using Yozeev.BusinessLogic.Stats.Dtos;
using Yozeev.Common;
using Abp.Domain.Entities.Auditing;
using Yozeev.Dtos;
using Yozeev.Controllers.Stats.Filters;
using Abp.Linq.Extensions;

namespace Yozeev.Controllers.Stats
{
    /// <summary>
    /// 航班检票统计
    /// </summary>
    [Route("api/Stats/[Controller]/[Action]")]
    public class ScheduleCheckController: YozeevControllerBase
    {
        private readonly IRepository<Schedule, Guid> _scheduleRep;

        private readonly IRepository<GateRecord, Guid> _gateRecordRepository;

        private readonly IRepository<Device, Guid> _deviceRepository;

        private readonly IQueryHelper _queryHelper;

        private readonly IRepository<TicketDetail, Guid> _ticketDetailRepository;

        private readonly IRepository<Ticket, Guid> _ticketRep;

        private readonly IRepository<Activity, Guid> _acitivityRep;

        private readonly AbstractFilter _routeFilter;

        private readonly AbstractFilter _boatFilter;

        private readonly AbstractFilter _ticketTypeFilter;

        private readonly AbstractFilter _wharfFilter;

        public ScheduleCheckController(
            IRepository<TicketDetail, Guid> ticketDetailRepository,
            IRepository<Device, Guid> deviceRepository,
            IRepository<GateRecord, Guid> gateRecordRepository,
            IRepository<Activity, Guid> activityRep,
            IRepository<Schedule, Guid> scheduleRep,
            IRepository<Ticket, Guid> ticketRep,
            RouteFilter routeFilter,
            TicketTypeFilter ticketTypeFilter,
            BoatFilter boatFilter,
            WharfFilter wharfFilter,
            IQueryHelper queryHelper)
        {
            _scheduleRep = scheduleRep;
            _acitivityRep = activityRep;
            _gateRecordRepository = gateRecordRepository;
            _ticketDetailRepository = ticketDetailRepository;
            _deviceRepository = deviceRepository;
            _ticketRep = ticketRep;
            _routeFilter = routeFilter;
            _ticketTypeFilter = ticketTypeFilter;
            _boatFilter = boatFilter;
            _wharfFilter = wharfFilter;
            _queryHelper = queryHelper;
        }

        /// <summary>
        /// 航班检票统计
        /// </summary>
        [HttpPost]
        public async Task<StatsPagedResultDto<ScheduleCheckResultDto>> GetPagedStat(ScheduleCheckInput input)
        {
            var schedules = _scheduleRep.GetAll()
                .Where(_queryHelper.WhereExp<Schedule>(input.queryData));
            var activities = _acitivityRep.GetAll();

            var checks = from activity in (
                            from act in activities
                            group act by act.ScheduleId
                            into g
                            select new 
                            { 
                                ScheduleId = g.Key,
                                TotalQuantity = g.Sum(act => act.TotalQuantity)
                            }
                         )
                       join ticketDetail in _ticketDetailRepository.GetAll()
                       on activity.ScheduleId equals ticketDetail.ScheduleId
                       select new
                       {
                           ScheduleId = activity.ScheduleId,
                           TotalQuantity = activity.TotalQuantity,
                           CheckedQuantity = ticketDetail.CheckedQuantity,
                           UncheckedQuantity = activity.TotalQuantity - ticketDetail.CheckedQuantity
                       };
            var sch = from schedule in schedules
                      orderby schedule.CreationTime descending
                      select new
                      {
                          schedule,
                          schedule.Route,
                          schedule.Boat
                      };

            var result = from check in checks
                         join schedule in sch
                         on check.ScheduleId equals schedule.schedule.Id
                         select new ScheduleCheckResultDto
                         {
                             Schedule = schedule.schedule,
                             Route = schedule.Route,
                             Boat = schedule.Boat,
                             TotalQuantity = check.TotalQuantity,
                             CheckedQuantity = check.CheckedQuantity,
                             UncheckedQuantity = check.UncheckedQuantity
                         };

            var count = result.Count();
            Dictionary<string, IEnumerable<object>> filters = new Dictionary<string, IEnumerable<object>>();
            _boatFilter.Decorate(filters);
            _routeFilter.Decorate(filters);
            _wharfFilter.Decorate(filters);
            return new StatsPagedResultDto<ScheduleCheckResultDto>(count, result.AsQueryable().PageBy(input).ToList(), filters);
        }

        /// <summary>
        /// 航班检票统计——详细
        /// </summary>
        [HttpPost]
        public async Task<PagedResultDto<ScheduleCheckDetailDto>> ScheduleDetailStat(string scheduleId)
        {
            var ticketDetails = _ticketDetailRepository.GetAll().Where(s => s.ScheduleId.ToString() == scheduleId);
            var tickets = _ticketRep.GetAll();

            var result = from ticketDetail in ticketDetails
                         select new ScheduleCheckDetailDto
                         {
                             Ticket = (from ticket in tickets
                                       where ticket.Id == ticketDetail.TicketId
                                       select ticket).FirstOrDefault(),
                             Schedule = ticketDetail.Schedule,
                             Customer = ticketDetail.Customer,
                             TicketDetail = ticketDetail
                         };

            var count = result.Count();
            return new PagedResultDto<ScheduleCheckDetailDto>(count, result.ToList());
        }
    }
}
